package com.sinosoft.weixin.utils;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

public class ZipUtil {
  /**
   * 将目录压缩成 zip 文件
   *
   * @param srcDir   源文件目录
   * @param destFile 目标目录
   */
  public static void zipDir(File srcDir, File destFile) throws IOException {
    if (!srcDir.isDirectory()) {
      throw new IllegalArgumentException(srcDir.getAbsolutePath()
              + " 不是目录！");
    }
    ZipArchiveOutputStream zip = null;
    try {
      zip = new ZipArchiveOutputStream(destFile);
      File[] files = srcDir.listFiles();
      for (File f : files) {
        addZipEntry(null, f, zip);
      }
    } finally {
      IOUtils.closeQuietly(zip);
    }
  }

  public static void extractZip(File zipFile, File destDir) throws IOException {
    if (!destDir.isDirectory()) {
      throw new IllegalArgumentException(destDir.getAbsolutePath()
              + " 不是目录！");
    }

    ZipArchiveInputStream zip = null;
    try {
      zip = new ZipArchiveInputStream(new FileInputStream(zipFile));
      ZipArchiveEntry entry = null;
      while ((entry = zip.getNextZipEntry()) != null) {
        File targetFile = new File(destDir, entry.getName());
        if (!targetFile.getParentFile().exists() || !targetFile.getParentFile().isDirectory()) {
          targetFile.getParentFile().mkdirs();
        }

        FileOutputStream out = new FileOutputStream(targetFile);
        IOUtils.copy(zip, out);
        IOUtils.closeQuietly(out);
      }
    } finally {
      IOUtils.closeQuietly(zip);
    }
  }

  public static String[] listZip(File zipFile) throws IOException {
    if (zipFile == null) {
      return null;
    }
    if (!zipFile.exists() || !zipFile.isFile()) {
      throw new IllegalArgumentException(zipFile.getAbsolutePath()
              + " 不是合法的文件！");
    }

    ZipArchiveInputStream zip = null;
    try {
      zip = new ZipArchiveInputStream(new FileInputStream(zipFile));
      List<String> entrys = new LinkedList<String>();
      ZipArchiveEntry entry;
      while ((entry = zip.getNextZipEntry()) != null) {
        if (!entry.isDirectory()) {
          entrys.add(entry.getName());
        }
      }
      return entrys.toArray(new String[entrys.size()]);
    } finally {
      IOUtils.closeQuietly(zip);
    }
  }

  private static void addZipEntry(String parentEntryName, File file,
                                  ZipArchiveOutputStream zip) throws IOException {
    String name = file.getName();
    if (parentEntryName != null) {
      name = parentEntryName + "/" + file.getName();
    }
    if (file.isFile()) {
      ZipArchiveEntry entry = new ZipArchiveEntry(name);
      entry.setSize(file.length());

      zip.putArchiveEntry(entry);
      BufferedInputStream in = new BufferedInputStream(
              new FileInputStream(file));

      byte[] buffer = new byte[2048];
      int count = 0;
      while ((count = in.read(buffer)) > 0) {
        zip.write(buffer, 0, count);
      }
      zip.closeArchiveEntry();
      in.close();
    } else if (file.isDirectory()) {
      File[] files = file.listFiles();
      for (File f : files) {
        addZipEntry(name, f, zip);
      }
    }
  }
}
